package cn.fastoo.common.sampleframe.dao.impl;

import cn.fastoo.common.exception.BizException;
import cn.fastoo.common.sampleframe.SqlUtils;
import cn.fastoo.common.sampleframe.dao.FastDao;
import cn.fastoo.common.sampleframe.search.Search;
import cn.fastoo.common.sampleframe.springside.Collections3;
import cn.fastoo.common.sampleframe.springside.SearchFilter;
import com.alibaba.fastjson.JSONObject;
import org.apache.ibatis.session.RowBounds;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import tk.mybatis.mapper.common.Mapper;
import tk.mybatis.mapper.entity.Example;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;


public class MybatisDaoImpl<T>   implements FastDao<T> {


	private Class<T> entityClass;

	protected Mapper mapper;

	public MybatisDaoImpl() {
		Type genType = this.getClass().getGenericSuperclass();
		ParameterizedType type = (ParameterizedType) genType;
		Type[] params = type.getActualTypeArguments();
		entityClass = (Class) params[0];
	}


	@Override
	public void update(T t) {
		try {
			if (mapper.updateByPrimaryKey(t) == 0) {
				throw BizException.DB_UPDATE_RESULT_0.newInstance("数据库操作,update返回0.{%s}", JSONObject.toJSONString(t));
			}
		} catch (Exception e) {
			e.printStackTrace();
			throw BizException.DB_EERROR.newInstance("数据库操作错误{%s}", e.getMessage());
		}
	}

	@Override
	public void insert(T t) {
		try {
			if (mapper.insert(t) == 0) {
				throw BizException.DB_INSERT_RESULT_0.newInstance("数据库操作,insert返回0.{%s}", JSONObject.toJSONString(t));
			}
			//SqlUtils.filledGeneratedField(t, keyHolder);
		} catch (Exception e) {
			e.printStackTrace();
			throw BizException.DB_EERROR.newInstance("数据库操作错误{%s}", e.getMessage());
		}
	}

	@Override
	public void delete(T t) {
		try {
			if(mapper.deleteByPrimaryKey(t) == 0){
				throw BizException.DB_DELETE_RESULT_0.newInstance("数据库操作,delete返回0,{%s}", t);
			}
		} catch (Exception e) {
			e.printStackTrace();
			throw BizException.DB_DELETE_RESULT_0.newInstance("数据库操作错误{%s}", e.getMessage());
		}
	}

	@Override
	public void delete(final Search search) {
		try {
			String sql = SqlUtils.getSearchDeleteSql(search, entityClass);
			if(mapper.deleteByExample(getExampleBySearch(search)) ==0){
				throw BizException.DB_DELETE_RESULT_0.newInstance("数据库操作,delete返回0,{%s}", sql);
			}
		} catch (Exception e) {
			e.printStackTrace();
			throw BizException.DB_DELETE_RESULT_0.newInstance("数据库操作错误{%s}", e.getMessage());
		}
	}

	@Override
	public void delete(Long id) {
		 delete(new Search().addSearchFilter("EQ_id", id));
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<T> find(Search search) {
		try {
			return mapper.selectByExample(getExampleBySearch(search));
		}catch (Exception e){
			throw BizException.DB_SELECT_ERROR.newInstance("数据库查询错误{%s}", e.getMessage());
		}
	}

	@Override
	public T findOne(Search search) {
		List<T> result = find(search);
		if (Collections3.isEmpty(result)) {
			return null;
		}
		return result.get(0);
	}

	@Override
	public T findById(Long id) {
		return findOne(new Search().addSearchFilter("EQ_id", id));
	}


	@SuppressWarnings("unchecked")
	@Override
	public Page<T> findPage(Search search) {

		Long count = count(search);
		String sql = null;
		try {
			List<T> result = find(search);
			return new PageImpl<T>(result, search.getPageRequest(), count);
		}catch (Exception e){
			throw BizException.DB_PAGE_ERROR.newInstance("数据库查询 findpage方法错误{%s}{%s}",sql, e.getMessage());

		}

	}

	public Example getExampleBySearch(final Search search){
		Example example = new Example(entityClass);
		for (SearchFilter t:search.values()) {
			switch (t.operator) {
				case EQ:
					example.createCriteria().andEqualTo(t.fieldName, t.value);
					break;
				case LIKE:
					example.createCriteria().andLike(t.fieldName, t.value.toString());
					break;
				case GT:
					example.createCriteria().andGreaterThan(t.fieldName, t.value);
					break;
				case LT:
					example.createCriteria().andLessThan(t.fieldName, t.value);
					break;
				case GTE:
					example.createCriteria().andGreaterThanOrEqualTo(t.fieldName, t.value);
					break;
				case LTE:
					example.createCriteria().andLessThanOrEqualTo(t.fieldName, t.value);
					break;
				case NEQ:
					example.createCriteria().andNotEqualTo(t.fieldName, t.value);
					break;
				case IN:
					example.createCriteria().andIn(t.fieldName, (Iterable) t.value);
					break;
				case NOTIN:
					example.createCriteria().andNotIn(t.fieldName, (Iterable) t.value);
					break;
				default:
					break;
			}
		}
		return example;
	}

	@Override
	public Long count(final Search search) {
		try {
			return new Long(mapper.selectCountByExample(getExampleBySearch(search)));
		}catch (Exception e){
			throw BizException.DB_SELECT_ERROR.newInstance("数据库查询 count方法错误{%s}", e.getMessage());
		}

	}

	@Override
	public void batchInsert(List<T> t) {
		/*
		BatchSql batchSql = null;
		try {
			batchSql = SqlUtils.getBatchInsertSql(t);
			int[] result  = jt.batchUpdate(batchSql.getSql(), batchSql.getBpss());
			for (int i :result) {
				if(i == 0){
					throw BizException.DB_BATCH_INSERT_RESULT_0.newInstance("数据库查询 批量插入错误}",batchSql.getSql());
				}
			}
		} catch (Exception e) {
			throw BizException.DB_BATCH_INSERT_RESULT_0.newInstance("数据库查询 批量插入错误{%s}{%s}",batchSql.getSql(), e.getMessage());
		}*/
	}

	@Override
	public List<T> findPageWithoutCount(final Search search) {
		String sql = null;
		try {
			RowBounds rowBounds = null;
			if(search.getPageRequest()!=null){
				rowBounds = new RowBounds(search.getPageRequest().getOffset(),
							search.getPageRequest().getPageSize()*search.getPageRequest().getPageSize());
			}
			return mapper.selectByExampleAndRowBounds(getExampleBySearch(search),rowBounds);
		}catch (Exception e){
			throw BizException.DB_PAGE_ERROR.newInstance("数据库查询 findPageWithoutCount{%s}{%s}",sql, e.getMessage());
		}
	}



}